home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / vector.lha / vector / hvector.h < prev    next >
C/C++ Source or Header  |  1991-11-23  |  7KB  |  265 lines

  1. #ifndef _HVECTOR_H
  2. #define _HVECTOR_H
  3.  
  4. #include "cvector.h"
  5.  
  6. // This is a template for a homogenous vector class (like a
  7. //  Cartesian vector but with a w scaling coordinate).
  8. // The usual operators are supplied.
  9.  
  10. #define HomogenousVectorDeclare(T)  \
  11. class HVec(T) {                            \
  12. public:                                \
  13.     static errorHandler error;                    \
  14.     static void badvec(int, const char *);            \
  15.     static errorHandler setErrorHandler(errorHandler);        \
  16.                                 \
  17.     T &operator[](int i) { return x[i]; }            \
  18.     T  operator()(int i) const { return x[i]; }            \
  19.        operator T*() { return x; }                \
  20.                                 \
  21.     HVec(T)() {}                        \
  22.                                 \
  23.     HVec(T)(T xval, T yval, T zval, T wval = 1) {        \
  24.     x[0] = xval; x[1] = yval; x[2] = zval; x[3] = wval;    \
  25.     }                                \
  26.                                 \
  27.     HVec(T)(const HVec(T) &v) {                    \
  28.     x[0] = v(0); x[1] = v(1); x[2] = v(2); x[3] = v(3);    \
  29.     }                                \
  30.                                 \
  31.     T magnitude() const {                    \
  32.     if (x[3] != 0)                        \
  33.         return sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]) / x[3]; \
  34.     else {                            \
  35.         (*error)(0, "w=0 in magnitude");            \
  36.         return 0;                        \
  37.     }                            \
  38.     }                                \
  39.                                 \
  40.     HVec(T) &normalize();                    \
  41.     HVec(T) &canonicalize();                    \
  42.                                 \
  43.     HVec(T) &operator+=(const HVec(T) &v);            \
  44.     HVec(T) &operator-=(const HVec(T) &v);            \
  45.                                 \
  46.     HVec(T) &operator*=(T s) {                    \
  47.     x[0] *= s;                        \
  48.     x[1] *= s;                        \
  49.     x[2] *= s;                        \
  50.     return *this;                        \
  51.     }                                \
  52.                                 \
  53.     HVec(T) &operator/=(T s) {                    \
  54.     T recip = 1.0 / s;                    \
  55.     x[0] *= recip;                        \
  56.     x[1] *= recip;                        \
  57.     x[2] *= recip;                        \
  58.     return *this;                        \
  59.     }                                \
  60.                                 \
  61.     /* Dehomogenize a homogenous vector */            \
  62.        operator CVec(T)() const;                \
  63.                                 \
  64.     /* Homogenize a cartesian vector */                \
  65.     HVec(T)(const CVec(T) &v) {                    \
  66.     x[0] = v(0); x[1] = v(1); x[2] = v(2); x[3] = 1;    \
  67.     }                                \
  68.                                 \
  69. protected:                            \
  70.     T        x[4];                        \
  71. };                                \
  72.                                 \
  73. /* -V */                            \
  74. inline HVec(T) operator-(const HVec(T) &v)            \
  75. {                                \
  76.     return HVec(T)(-v(0), -v(1), -v(2), v(3));            \
  77. }                                \
  78.                                 \
  79. /* s * V */                            \
  80. inline HVec(T) operator*(T s, const HVec(T) &v)            \
  81. {                                \
  82.     return HVec(T)(s * v(0), s * v(1), s * v(2), v(3));        \
  83. }                                \
  84.                                 \
  85. /* V * s */                            \
  86. inline HVec(T) operator*(const HVec(T) &v, T s) {        \
  87.     return s * v;                        \
  88. }                                \
  89.                                 \
  90. /* V / s */                            \
  91. inline HVec(T) operator/(const HVec(T) &v, T s)            \
  92. {                                \
  93.     T recip = 1.0 / s;                        \
  94.     return HVec(T)(v(0)*recip, v(1)*recip, v(2)*recip, v(3));    \
  95. }                                \
  96.                                 \
  97. /* V + V */                            \
  98. HVec(T) operator+(const HVec(T) &a, const HVec(T) &b);        \
  99.                                 \
  100. /* V - V */                            \
  101. HVec(T) operator-(const HVec(T) &a, const HVec(T) &b);        \
  102.                                 \
  103. /* V cross V */                            \
  104. HVec(T) operator^(const HVec(T) &a, const HVec(T) &b);        \
  105.                                 \
  106. /* V dot V */                            \
  107. inline T operator*(const HVec(T) &a, const HVec(T) &b)        \
  108. {                                \
  109.     return (a(0) * b(0) + a(1) * b(1) + a(2) * b(2)) /        \
  110.        (a(3) * b(3));                    \
  111. }                                \
  112.                                 \
  113. /* V == V (no fuzz for comparison) */                \
  114. int operator==(const HVec(T) &a, const HVec(T) &b);        \
  115.                                 \
  116. /* V != V (no fuzz for comparison) */                \
  117. inline int operator!=(const HVec(T) &a, const HVec(T) &b) {    \
  118.     return !(a == b);                        \
  119. }                                \
  120.                                 \
  121. ostream &operator<<(ostream &o, const HVec(T) &v);
  122.  
  123. #define HomogenousVectorImplement(T) \
  124.                                 \
  125. errorHandler HVec(T)::error = &HVec(T)::badvec;            \
  126.                                 \
  127. void HVec(T)::badvec(int code, const char *msg) {        \
  128.     cerr << "HVec(T): error " << code << ": "            \
  129.      << msg << endl;                    \
  130. }                                \
  131.                                 \
  132. errorHandler HVec(T)::setErrorHandler(errorHandler e) {        \
  133.     errorHandler old = HVec(T)::error;                \
  134.     HVec(T)::error = e;                        \
  135.     return old;                            \
  136. }                                \
  137.                                 \
  138.                                 \
  139. HVec(T) &HVec(T)::normalize() {                    \
  140.     T mag = this->magnitude();                    \
  141.                                 \
  142.     if (mag != 0.0) {                        \
  143.     mag = 1 / (mag * x[3]);                    \
  144.     x[0] *= mag;                        \
  145.     x[1] *= mag;                        \
  146.     x[2] *= mag;                        \
  147.     x[3] = 1;                        \
  148.     }                                \
  149.                                 \
  150.     return *this;                        \
  151. }                                \
  152.                                 \
  153. HVec(T) &HVec(T)::canonicalize() {                \
  154.     if (x[3] == 0)                        \
  155.     (*error)(1, "w=0 in canonicalize");            \
  156.     else if (x[3] != 1) {                    \
  157.     float recip = 1 / x[3];                    \
  158.     x[0] *= recip;                        \
  159.     x[1] *= recip;                        \
  160.     x[2] *= recip;                        \
  161.     x[3] = 1;                        \
  162.     }                                \
  163.     return *this;                        \
  164. }                                \
  165.                                 \
  166. HVec(T) &HVec(T)::operator+=(const HVec(T) &v) {        \
  167.     if (x[3] != v(3)) {                        \
  168.     HVec(T) tv(v);                        \
  169.     canonicalize();                        \
  170.     tv.canonicalize();                    \
  171.     x[0] += tv(0);                        \
  172.     x[1] += tv(1);                        \
  173.     x[2] += tv(2);                        \
  174.     } else {                            \
  175.     x[0] += v(0);                        \
  176.     x[1] += v(1);                        \
  177.     x[2] += v(2);                        \
  178.     }                                \
  179.     return *this;                        \
  180. }                                \
  181.                                 \
  182. HVec(T) &HVec(T)::operator-=(const HVec(T) &v) {        \
  183.     if (x[3] != v(3)) {                        \
  184.     HVec(T) tv(v);                        \
  185.     canonicalize();                        \
  186.     tv.canonicalize();                    \
  187.     x[0] -= tv(0);                        \
  188.     x[1] -= tv(1);                        \
  189.     x[2] -= tv(2);                        \
  190.     } else {                            \
  191.     x[0] -= v(0);                        \
  192.     x[1] -= v(1);                        \
  193.     x[2] -= v(2);                        \
  194.     }                                \
  195.     return *this;                        \
  196. }                                \
  197.                                 \
  198. HVec(T) operator+(const HVec(T) &a, const HVec(T) &b)        \
  199. {                                \
  200.     if (a(3) != b(3)) {                        \
  201.     HVec(T) ta = a;                        \
  202.     HVec(T) tb = b;                        \
  203.     ta.canonicalize();                    \
  204.     tb.canonicalize();                    \
  205.     return HVec(T)(ta(0)+tb(0), ta(1)+tb(1), ta(2)+tb(2));    \
  206.     } else                            \
  207.     return HVec(T)(a(0)+b(0), a(1)+b(1), a(2)+b(2), a(3));    \
  208. }                                \
  209.                                 \
  210. HVec(T) operator-(const HVec(T) &a, const HVec(T) &b)        \
  211. {                                \
  212.     if (a(3) != b(3)) {                        \
  213.     HVec(T) ta = a;                        \
  214.     HVec(T) tb = b;                        \
  215.     ta.canonicalize();                    \
  216.     tb.canonicalize();                    \
  217.     return HVec(T)(ta(0)-tb(0), ta(1)-tb(1), ta(2)-tb(2));    \
  218.     } else                            \
  219.     return HVec(T)(a(0)-b(0), a(1)-b(1), a(2)-b(2), a(3));    \
  220. }                                \
  221.                                 \
  222. HVec(T) operator^(const HVec(T) &a, const HVec(T) &b)        \
  223. {                                \
  224.     HVec(T) ta(a);                        \
  225.     HVec(T) tb(b);                        \
  226.     ta.canonicalize();                        \
  227.     tb.canonicalize();                        \
  228.     return HVec(T)(ta(1) * tb(2) - ta(2) * tb(1),        \
  229.            ta(2) * tb(0) - ta(0) * tb(2),        \
  230.            ta(0) * tb(1) - ta(1) * tb(0));        \
  231. }                                \
  232.                                 \
  233. int operator==(const HVec(T) &a, const HVec(T) &b)        \
  234. {                                \
  235.     if (a(3) != b(3)) {                        \
  236.     HVec(T) ta(a);                        \
  237.     HVec(T) tb(b);                        \
  238.     ta.canonicalize();                    \
  239.     tb.canonicalize();                    \
  240.     return (ta(0) == tb(0)) &&                \
  241.            (ta(1) == tb(1)) &&                \
  242.            (ta(2) == tb(2));                \
  243.     } else                            \
  244.     return (a(0) == b(0)) &&                \
  245.            (a(1) == b(1)) &&                \
  246.            (a(2) == b(2));                    \
  247. }                                \
  248.                                 \
  249. HVec(T)::operator CVec(T)() const {                \
  250.     HVec(T) a(*this);                        \
  251.     a.canonicalize();                        \
  252.     return CVec(T)(a(0), a(1), a(2));                \
  253. }                                \
  254.                                 \
  255. ostream &operator<<(ostream &o, const HVec(T) &v) {        \
  256.     return o << "( " << v(0) << ' ' << v(1) << ' '        \
  257.              << v(2) << ' ' << v(3) << " )";        \
  258. }
  259.  
  260. HomogenousVectorDeclare(float);
  261.  
  262. typedef HVec(float) HVector;
  263.  
  264. #endif /*_HVECTOR_H*/
  265.